package com.srwl.mytx.activity;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Chronometer;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.alibaba.fastjson.JSONObject;
import com.srwl.mytx.Constant;
import com.srwl.mytx.Helper;
import com.srwl.mytx.R;
import com.srwl.mytx.RetrofitManager;
import com.srwl.mytx.dao.DBManager;
import com.srwl.mytx.domain.CommonResult;
import com.srwl.mytx.domain.User;
import com.srwl.mytx.service.UserService;
import com.srwl.mytx.utils.ClickUtil;
import com.srwl.mytx.utils.GlideLoadUtils;
import com.srwl.mytx.utils.PermissionsUtils;
import com.srwl.mytx.widget.ConfirmDialog;
import com.starrtc.starrtcsdk.api.XHClient;
import com.starrtc.starrtcsdk.api.XHConstants;
import com.starrtc.starrtcsdk.api.XHCustomConfig;
import com.starrtc.starrtcsdk.api.XHVoipManager;
import com.starrtc.starrtcsdk.apiInterface.IXHResultCallback;
import com.starrtc.starrtcsdk.core.audio.StarRTCAudioManager;
import com.starrtc.starrtcsdk.core.pusher.XHCameraRecorder;

import java.util.List;
import java.util.Set;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class AudioChatActivity extends BaseActivity implements View.OnClickListener {
    private static final String TAG = "AudioChatActivity";
    private XHVoipManager voipManager;
    private Chronometer timer;

    public static String ACTION = "ACTION";
    public static String RING = "RING";
    public static String CALLING = "CALLING";
    private String action;
    private String targetId;
    private User targetUser;
    private BroadcastReceiver receiver;
    private LocalBroadcastManager broadcastManager;
    private StarRTCAudioManager starRTCAudioManager;
    private ImageView iv_avatar;
    private TextView tv_status;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_audio_chat_connect);
        starRTCAudioManager = StarRTCAudioManager.create(this.getApplicationContext());
        starRTCAudioManager.start(new StarRTCAudioManager.AudioManagerEvents() {
            @Override
            public void onAudioDeviceChanged(StarRTCAudioManager.AudioDevice selectedAudioDevice, Set availableAudioDevices) {
                Log.d("onAudioDeviceChanged ", selectedAudioDevice.name());
            }
        });
        XHCustomConfig customConfig = XHCustomConfig.getInstance(this);
        customConfig.setDefConfigAudioSource(XHConstants.XHAudioSourceEnum.VOICE_COMMUNICATION);
        customConfig.setDefConfigAudioStreamType(XHConstants.XHAudioStreamTypeEnum.STREAM_VOICE_CALL);
        voipManager = XHClient.getInstance().getVoipManager();
        voipManager.setRtcMediaType(XHConstants.XHRtcMediaTypeEnum.STAR_RTC_MEDIA_TYPE_AUDIO_ONLY);
        voipManager.setRecorder(new XHCameraRecorder());
        registerBroadcastReceiver();
        targetUser = getIntent().getParcelableExtra("targetUserInfo");
        if (targetUser == null) {
            targetId = getIntent().getStringExtra("userId");
            targetUser = Helper.getInstance().getContactUserInfo(targetId);
            if (targetUser == null) {
                getUserInfo(targetId);
            }
        } else {
            targetId = targetUser.getuId();
        }
        action = getIntent().getStringExtra(ACTION);
        timer = findViewById(R.id.timer);
        iv_avatar = findViewById(R.id.iv_avatar);
        tv_status = findViewById(R.id.tv_status);
        showTargetUserInfo();
        findViewById(R.id.iv_close_call).setOnClickListener(this);


    }

    /**
     * 呼叫或者接听
     * 必须在权限校验之后执行
     */
    private void callOrPickup() {
        if (action.equals(CALLING)) {
            Log.d("newVoip", "call");
            voipManager.audioCall(this, targetId, new IXHResultCallback() {
                @Override
                public void success(Object data) {
                    Log.d("newVoip", "call success");
                }

                @Override
                public void failed(String errMsg) {
                    Log.d("newVoip", "call failed");
                    stopAndFinish();
                }
            });
        } else {
            Log.d("newVoip", "onPickup");
            onPickup();
        }
    }


    @Override
    protected void onStart() {
        super.onStart();
        String[] permissions = new String[]{Manifest.permission.RECORD_AUDIO,};
        PermissionsUtils.getInstance().checkPermissions(this, permissions, new PermissionsUtils.IPermissionsResult() {
            @Override
            public void onGranted() {
                callOrPickup();
            }

            @Override
            public void onDenied(List<String> deniedPermissionList) {
                StringBuilder tips = new StringBuilder();
                for (String permission : deniedPermissionList) {
                    if (Manifest.permission.RECORD_AUDIO.equals(permission)) {
                        tips.append("[麦克风] ");
                    }
                }
                ConfirmDialog dialog = new ConfirmDialog(AudioChatActivity.this, "提醒", "使用 " + tips + "的权限被禁止，去设置？", "去设置", "取消", true);
                dialog.setConfirmListener(new ConfirmDialog.ConfirmListener() {
                    @Override
                    public void confirm() {
                        Uri packageURI = Uri.parse("package:" + getPackageName());
                        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
                        startActivity(intent);
                    }
                });
                dialog.setCancelListener(new ConfirmDialog.CancelListener() {
                    @Override
                    public void cancel() {
                        finish();
                    }
                });
                dialog.setCanceledOnTouchOutside(false);
                dialog.show();
            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        PermissionsUtils.getInstance().onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    private void showTargetUserInfo() {
        if (targetUser != null) {
            // Glide.with(this).load(targetUser.getAvatar()).error(R.drawable.tx_default_avatar_1).into(iv_avatar);
            GlideLoadUtils.glideLoad(this, targetUser.getAvatar(), iv_avatar, R.drawable.tx_default_avatar_1);
            String username = targetUser.getUsername();
            if (username == null) {
                username = targetUser.getNick();
            }
            ((TextView) findViewById(R.id.tv_nick)).setText(username);
        }
    }

    private void setupView() {
        voipManager.setupView(null, null, new IXHResultCallback() {
            @Override
            public void success(Object data) {
                Log.d("newVoip", "setupView success");

            }

            @Override
            public void failed(String errMsg) {
                Log.d("newVoip", "setupView failed");
                if (action.equals(CALLING)) {
                    tv_status.setText("发起语音呼叫失败");
                } else {
                    tv_status.setText("接受语音呼叫失败");

                }
                stopAndFinish();
            }
        });
        if (action.equals(CALLING)) {
            // showCallingView();
        }
    }


    @Override
    public void onResume() {
        super.onResume();

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        broadcastManager.unregisterReceiver(receiver);
        if (starRTCAudioManager != null) {
            starRTCAudioManager.stop();
        }
        PermissionsUtils.getInstance().clear();
    }

    @Override
    public void onBackPressed() {
        new AlertDialog.Builder(AudioChatActivity.this).setCancelable(true)
                .setTitle("是否挂断?")
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface arg0, int arg1) {

                    }
                }).setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface arg0, int arg1) {
                        timer.stop();
                        voipManager.hangup(new IXHResultCallback() {
                            @Override
                            public void success(Object data) {
                                stopAndFinish();
                            }

                            @Override
                            public void failed(final String errMsg) {
                                Log.e("", "AEVENT_VOIP_ON_STOP errMsg:" + errMsg);
                                //  showToast(AudioChatActivity.this,errMsg);

                            }
                        });
                    }
                }
        ).show();
    }


    private void showCallingView() {
        tv_status.setVisibility(View.VISIBLE);
        timer.setVisibility(View.INVISIBLE);
    }

    private void showTalkingView() {
        tv_status.setText("已接通");
        timer.setVisibility(View.VISIBLE);
        timer.setBase(SystemClock.elapsedRealtime());
        timer.start();
        setupView();
    }

    private void onPickup() {
        voipManager.accept(this, targetId, new IXHResultCallback() {
            @Override
            public void success(Object data) {
                Log.d("newVoip", "onPickup OK ");
            }

            @Override
            public void failed(String errMsg) {
                Log.d("newVoip", "onPickup failed ");
                stopAndFinish();
            }
        });
        showTalkingView();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.iv_close_call:
                if (ClickUtil.isFastClick()) {
                    return;
                }
                voipManager.hangup(new IXHResultCallback() {
                    @Override
                    public void success(Object data) {
                        stopAndFinish();
                    }

                    @Override
                    public void failed(String errMsg) {
                        stopAndFinish();
                    }
                });
                break;
        }
    }

    private void stopAndFinish() {
        if (starRTCAudioManager != null) {
            starRTCAudioManager.stop();
        }

        postDelayedFinish(1500);
    }

    private void registerBroadcastReceiver() {

        broadcastManager = LocalBroadcastManager.getInstance(this);
        IntentFilter filter = new IntentFilter();

        filter.addAction(Constant.ACTION_ON_HANG_UP);
        filter.addAction(Constant.ACTION_ON_CALL_ERROR);
        filter.addAction(Constant.ACTION_ON_AUDIO_CONNECT);
        filter.addAction(Constant.ACTION_ON_CALL_BE_REFUSE);
        filter.addAction(Constant.ACTION_ON_CALL_BUSY);

        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {

                switch (intent.getAction()) {

                    case Constant.ACTION_ON_AUDIO_CONNECT:
                        showTalkingView();
                        break;
                    case Constant.ACTION_ON_HANG_UP:
                        tv_status.setText("对方已经挂断");
                        stopAndFinish();
                        break;
                    case Constant.ACTION_ON_CALL_ERROR:
                        tv_status.setText("发起语音通话出错");
                        stopAndFinish();
                        break;
                    case Constant.ACTION_ON_CALL_BE_REFUSE:
                        tv_status.setText("对方拒绝接听");
                        stopAndFinish();
                        break;
                    case Constant.ACTION_ON_CALL_BUSY:
                        tv_status.setText("对方正在通话中");
                        stopAndFinish();
                        break;
                }
            }
        };
        broadcastManager.registerReceiver(receiver, filter);

    }

    private void postDelayedFinish(int delayMillis) {
        Helper.getInstance().setStartingCall(false);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                finish();
            }
        }, delayMillis);
    }

    /**
     * 远程查询用户信息
     *
     * @param userId
     */
    private void getUserInfo(String userId) {
        RetrofitManager.getInstance().createRequest(UserService.class)
                .getUserInfo(userId)
                .enqueue(new Callback<CommonResult>() {
                    @Override
                    public void onResponse(Call<CommonResult> call, Response<CommonResult> response) {
                        CommonResult result = response.body();
                        if (!response.isSuccessful() || result == null) {
                            Log.e(TAG, "onResponse:从服务端获取联系人信息出错 " + response.message());
                            return;
                        }

                        if (result.isError()) {
                            Log.e(TAG, "onResponse:从服务端获取联系人信息出错 " + result.getMsg());
                            return;
                        }

                        JSONObject object = (JSONObject) result.getData();

                        User user = object.toJavaObject(User.class);
                        user.setUId(userId);
                        user.setType(Constant.USER_TYPE_TEMP);
                        DBManager.getInstance().getDaoSession().getUserDao().insertOrReplace(user);//作为临时联系人，保存在用户表中
                        targetUser = user;
                        showTargetUserInfo();
                    }

                    @Override
                    public void onFailure(Call<CommonResult> call, Throwable t) {

                        Log.e(TAG, "onFailure: " + t.getMessage());
                    }
                });
    }


}
